home *** CD-ROM | disk | FTP | other *** search
/ Electronic Clipper 1995 April / Electronic Clipper 1995-04.iso / pc / pc_users / ideasrc / setup / pviewer / framewnd.c < prev    next >
Text File  |  1993-04-17  |  40KB  |  1,007 lines

  1.  
  2. // ---------------------------------------------------------------------
  3. //
  4. // FrameWnd.c - Picture Viewer - QuickTime for Windows
  5. //
  6. //              Version 1.0
  7. //
  8. //              (c) 1988-1992 Apple Computer, Inc. All Rights Reserved.
  9. //
  10. // ---------------------------------------------------------------------
  11.  
  12.  
  13. // Includes
  14. // --------
  15.    #define NOMINMAX
  16.    #include <Windows.H>                // Required by Windows
  17.    #include <commdlg.h>                // Header file for common dlgs
  18.    #include <dlgs.h>                   // Header file for common dlgs ids
  19.    #include <cderr.h>                  // Header file for error ids
  20.    #include <memory.h>                 // Needed for memset() function
  21.    #include <shellapi.h>               // Drag and drop stuff
  22.  
  23.    #include <qtole.h>                  // Interface to qtole dll
  24.  
  25.    #include "common.h"                 // Interface to common.c
  26.  
  27.    #include "viewer.h"                 // Interface to other *.c files
  28.    #include "viewer.hr"                // Defines used in *.rc files
  29.    #include "picture.h"                // Interface to other *.c files
  30.    
  31. // Message-Persistent Data
  32. // -----------------------
  33.    static struct                       // Hungarian notation: g
  34.      { HWND      hwndClient;           // MDI client window
  35.        WORD      wNumPictures;         // Number of picture wnds
  36.        BOOL      bUserAbortPrint;      // User abort print flag
  37.        HWND      hwndCancelPrt;        // Handle of print cancel dlg
  38.        HBITMAP   hAboutBitmap;         // Temp static storage of bitmap
  39.                                        // displayed in about dialogs
  40.      } g;
  41.  
  42.  
  43. // Exported callback functions
  44. // ----------------------------
  45.    BOOL __export CALLBACK AboutDlgProc       (HWND, UINT, WPARAM, LPARAM);
  46.    BOOL __export CALLBACK CloseEnumProc      (HWND, LPARAM);
  47.    BOOL __export CALLBACK PaletteEnumProc    (HWND, LPARAM);
  48.    BOOL __export CALLBACK PrintCancelDlgProc (HWND, UINT, WPARAM, LPARAM);
  49.    int  __export CALLBACK PrintAbortProc     (HDC, int);
  50.    UINT __export CALLBACK PrintDlgHookProc   (HWND, UINT, WPARAM, LPARAM);
  51.  
  52. // Internal Function Declarations
  53. // ------------------------------
  54.    static LONG NEAR ViewerFrameCreate       (HWND);
  55.    static LONG NEAR ViewerFileCommands      (HWND, WPARAM, WORD);
  56.    static LONG NEAR ViewerWindowCommands    (HWND, WPARAM, WORD);
  57.    static LONG NEAR ViewerHelpCommands      (HWND, WPARAM, WORD);
  58.    static LONG NEAR LaunchPictureWnd        (LPSTR, LPSTR);
  59.    static VOID NEAR ViewerEnableMenus       (HWND, BOOL);
  60.    static VOID NEAR TellUserCommonDlgError  (DWORD);
  61.    static LONG NEAR ProcessDroppedFiles     (HWND, WPARAM );
  62.    static VOID NEAR DestroyHelpInstance     (HWND);
  63.  
  64. // -----------------------------------------------------------------------
  65.  
  66.  
  67. // Function: ViewerFrameWndProc - Viewer Frame Window Procedure
  68. // --------------------------------------------------------------------
  69. // Parameters: As required by Microsoft Windows
  70. //
  71. // Returns:    Via DefFrameProc
  72. // --------------------------------------------------------------------
  73.    LONG __export CALLBACK ViewerFrameWndProc
  74.               (HWND hwndFrame, UINT message, WPARAM wParam, LPARAM lParam)
  75.  
  76.      {WNDENUMPROC       lpfnEnumPictures;   // -> callback funcion for
  77.                                             // enumeration of pictures
  78.       HWND              hwndPicture;        // Temp handle of active picture wnd
  79.       LPQTOLE_OLEDATA   lpOleData;          // -> to OLE data
  80.  
  81.  
  82.       switch( message ) 
  83.         {case WM_CREATE:
  84.             return ViewerFrameCreate( hwndFrame );
  85.  
  86.          case WM_PALETTECHANGED:
  87.             if( g.wNumPictures &&
  88.                    ( lpfnEnumPictures = (WNDENUMPROC) MakeProcInstance
  89.                         ( (FARPROC) PaletteEnumProc, ViewerQueryInstance())))
  90.                {StoreCurrentSystemPalette( NULL );
  91.  
  92.                    // Tell the picture wnds to repaint themselves
  93.                 EnumChildWindows( g.hwndClient, lpfnEnumPictures,
  94.                                                           (LPARAM) wParam);
  95.                 FreeProcInstance( (FARPROC) lpfnEnumPictures );
  96.                }
  97.  
  98.             return 0L;
  99.             
  100.          case WM_INITMENUPOPUP:
  101.    // Set check marks and enable menu items in popups
  102.             if( !(BOOL) HIWORD( lParam ) &&
  103.                 ( hwndPicture = (HWND) SendMessage
  104.                           ( g.hwndClient, WM_MDIGETACTIVE, 0, 0L )) &&
  105.                                                   IsWindow( hwndPicture ))
  106.                 SendMessage( hwndPicture,
  107.                                     WM_VIEWER_INITPOPUPS, wParam, lParam );
  108.  
  109.             return 0L;
  110.  
  111.          case WM_COMMAND:
  112.             switch( wParam )
  113.                {case VIEWER_FILE_OPEN:        // file menu popup
  114.                 case VIEWER_FILE_CLOSE:
  115.                 case VIEWER_FILE_PRTSETUP:
  116.                 case VIEWER_FILE_PRINT:
  117.                 case VIEWER_FILE_EXIT:
  118.                     return ViewerFileCommands
  119.                                     ( hwndFrame, wParam, HIWORD (lParam));
  120.  
  121.                 case VIEWER_WINDOW_TILE:      // window menu popup
  122.                 case VIEWER_WINDOW_CASCADE:
  123.                 case VIEWER_WINDOW_ARRANGE:
  124.                     return ViewerWindowCommands
  125.                                     ( hwndFrame, wParam, HIWORD (lParam));
  126.  
  127.  
  128.                 case VIEWER_HELP_VIEWERHELP: // help menu popup
  129.                 case VIEWER_HELP_USINGHELP:
  130.                 case VIEWER_HELP_ABOUTVIEWER:
  131.                     return ViewerHelpCommands
  132.                                     ( hwndFrame, wParam, HIWORD (lParam));
  133.  
  134.                 default:
  135.                     if( ( hwndPicture = (HWND) SendMessage
  136.                              ( g.hwndClient, WM_MDIGETACTIVE, 0, 0L )) &&
  137.                                                    IsWindow( hwndPicture ))
  138.                         SendMessage( hwndPicture,
  139.                                                WM_COMMAND, wParam, lParam );
  140.  
  141.                     break;  // break to DefFrameProc
  142.                }
  143.  
  144.             break;
  145.  
  146.     // WM_USER messages
  147.  
  148.          case WM_VIEWER_CMDLINE:
  149.             return LaunchPictureWnd( (LPSTR) lParam, NULL );
  150.  
  151.          case WM_VIEWER_PICTUREDELETED:
  152.    // Decrement picture count. This is incremented in LaunchPictureWnd
  153.    // when picture is created
  154.             if( --g.wNumPictures <= 0 )
  155.                 ViewerEnableMenus( hwndFrame, FALSE );
  156.             return 0L;
  157.  
  158.     // These next messages are posted by the ole callback function in PictUtl.c
  159.          case WM_VIEWER_OLE_OPTIONSDLG:
  160.             ViewerGetOptions( NULL, (LPQTOLE_OPTIONSPICTURE) lParam );
  161.             return 0L;
  162.  
  163.          case WM_VIEWER_OLE_PLAYOBJECT:
  164.             QTOLE_PlayObject( ViewerQueryOleData(), lParam );
  165.             return 0L;
  166.  
  167.  
  168.     // end WM_USER messages
  169.  
  170.  
  171.     // Standard drag and drop processing. Allows for multiple pictures but
  172.     // does not worry about position of drop
  173.          case WM_DROPFILES:
  174.             return ProcessDroppedFiles( hwndFrame, wParam );
  175.  
  176.          case WM_QUERYENDSESSION:
  177.          case WM_CLOSE:
  178.             if( g.wNumPictures && 
  179.                     ( lpfnEnumPictures = (WNDENUMPROC) MakeProcInstance
  180.                         ( (FARPROC) CloseEnumProc, ViewerQueryInstance())))
  181.                 {  // Give all pictures a chance to stop the close
  182.                  EnumChildWindows( g.hwndClient, lpfnEnumPictures, 0L );
  183.                  FreeProcInstance( (FARPROC) lpfnEnumPictures );
  184.  
  185.                    // If someone didn't want to close, don't kill the app
  186.                  if( NULL != GetWindow( g.hwndClient, GW_CHILD ))
  187.                      return 0L;
  188.                 }
  189.  
  190.                // Tell qtole.dll that we are closing the server
  191.                // Don't close if QTOLE_ClosingServerWnd returns FALSE;
  192.             if( ( lpOleData = ViewerQueryOleData()) && 
  193.                          lpOleData->lpqtoleServer &&
  194.                                   !QTOLE_ClosingServerWnd( lpOleData, message ))
  195.                 return 0L;
  196.  
  197.             break;    // break to DefFrameProc
  198.  
  199.  
  200.          case WM_NCDESTROY:
  201.             DragAcceptFiles( hwndFrame, FALSE );
  202.  
  203.                // Destroy help instance
  204.             DestroyHelpInstance( hwndFrame );
  205.  
  206.                // NULL the global hwnds in viewmain.c
  207.             ViewerNoMoreWindow();
  208.  
  209.             PostQuitMessage( 0 );
  210.             break;
  211.  
  212.         }
  213.  
  214.       return DefFrameProc
  215.                      ( hwndFrame, g.hwndClient, message, wParam, lParam );
  216.      }
  217.  
  218.  
  219. // Function: ViewerFrameCreate - process WM_CREATE message
  220. // --------------------------------------------------------------------
  221. // Parameters: HWND hwndFrame;         Frame window
  222. //
  223. // Returns:    0L if OK, else returns -1L to kill app
  224. // --------------------------------------------------------------------
  225.    static LONG NEAR ViewerFrameCreate( HWND hwndFrame )
  226.  
  227.      {CLIENTCREATESTRUCT  clientcreate;    // MDI client create struct
  228.       char                szCaption[50];   // caption buffer;
  229.  
  230.  
  231.       szCaption[0] = '\0';
  232.       if( LoadString( ViewerQueryResources(), VIEWER_STRING_CAPTION,
  233.                                           szCaption, sizeof( szCaption )))
  234.           SetWindowText( hwndFrame, szCaption );
  235.    // No point in trying for an error message here since it probably won't
  236.    // load either.
  237.  
  238.    // disable menu items until a picture is created
  239.       g.wNumPictures = 0;
  240.       ViewerEnableMenus( hwndFrame, FALSE );
  241.  
  242.       DragAcceptFiles( hwndFrame, TRUE );
  243.  
  244.       clientcreate.hWindowMenu =
  245.                       GetSubMenu( GetMenu( hwndFrame ), MENU_WINDOW_POS );
  246.       clientcreate.idFirstChild = VIEWER_CLIENT_FIRSTCHILD;
  247.  
  248.       if( !(g.hwndClient = CreateWindow( "MDICLIENT", NULL,
  249.                     WS_CHILD | WS_CLIPCHILDREN | WS_VISIBLE |
  250.                                             WS_HSCROLL | WS_VSCROLL ,
  251.                     0, 0, 0, 0, hwndFrame, ( HMENU) 1,
  252.                     ViewerQueryInstance(), (LPVOID) &clientcreate )))
  253.           return -1L;                 // return -1 to kill app
  254.       else
  255.           return  0L;
  256.      }
  257.  
  258.  
  259. // Function: ViewerFileCommands - Process WM_COMMAND, File popup messages
  260. // --------------------------------------------------------------------
  261. // Parameters: HWND   hwndFrame;      Frame window
  262. //             WORD   wIDItem;        Menu or control id
  263. //             WORD   wNotifyCode;    notification message
  264. //
  265. // Returns:    LONG   generally 0L
  266. // --------------------------------------------------------------------
  267.    static LONG NEAR ViewerFileCommands
  268.                        (HWND hwndFrame, WPARAM wIDItem, WORD wNotifyCode )
  269.  
  270.      {HWND          hwndPicture;                  // Handle of picture window
  271.       OPENFILENAME  ofn;                          // OPENFILENAME struct
  272.       UINT          cbString;                     // Length of filter string
  273.       char          szPicturePath[MAX_PATH_LEN];  // Picture file path.
  274.                                                   // Must be at least 256 bytes
  275.       char          szPictureName[MAX_NAME_LEN];  // Picture file name
  276.       char          szFilter[MAX_PATH_LEN];       // Picture file filter str
  277.       LPSTR         lpTemp;                       // Temp -> to string
  278.       LPSTR         lpSave;                       // Temp -> to string
  279.       char          chReplace;                    // String separator used in filter string
  280.       DWORD         dwError;                      // Common dlg error return
  281.       PRINTDLG      pd;                           // Print common dlg struct
  282.       ABORTPROC     lpPrintAbortProc;             // -> to Print abort proc
  283.       DLGPROC       lpPrtCancelProc;              // -> to Print cancel dlg proc
  284.       WORD          wIDError;                     // Resource error string id
  285.       int           nError;                       // Error return
  286.  
  287.       static DWORD  dwFilterIndex = 1;            // Filter index. Saved between 
  288.                                                   // invocations of dialog
  289.  
  290.    typedef UINT ( CALLBACK * PRINTDLGHOOKPROC ) (HWND, UINT, WPARAM, LPARAM );
  291.  
  292.  
  293.       switch( wIDItem )
  294.         {case VIEWER_FILE_OPEN:
  295.             memset( &ofn, 0, sizeof( OPENFILENAME ));
  296.             szPicturePath[0] = '\0';
  297.  
  298.             if( !(cbString = LoadString( ViewerQueryResources(),
  299.                                   VIEWER_STRING_OPENPICTFILTER,
  300.                                           szFilter, sizeof( szFilter ))))
  301.                 return 0L;
  302.  
  303.    // See 3.1 SDK manuals, vol 1 for examples of common dlg processing
  304.             lpTemp = szFilter + lstrlen( szFilter );
  305.             chReplace = *AnsiPrev( szFilter, lpTemp );
  306.             lpTemp = szFilter;
  307.             while( *lpTemp )
  308.                 {if( *lpTemp == chReplace )
  309.                     {  // Need to increment pointer past chReplace before
  310.                        // setting to NULL. Otherwise AnsiNext thinks it is
  311.                        // at end of string and quits
  312.                      lpSave = lpTemp;
  313.                      lpTemp = AnsiNext( lpTemp );
  314.                      *lpSave = '\0';
  315.                     }
  316.                  else
  317.                      lpTemp = AnsiNext( lpTemp );
  318.                 }
  319.  
  320.             ofn.lStructSize    = sizeof( OPENFILENAME );
  321.             ofn.hwndOwner      = hwndFrame;
  322.             ofn.lpstrFilter    = szFilter;
  323.             ofn.nFilterIndex   = dwFilterIndex;
  324.             ofn.lpstrFile      = szPicturePath;
  325.             ofn.nMaxFile       = sizeof( szPicturePath );
  326.             ofn.lpstrFileTitle = szPictureName;
  327.             ofn.nMaxFileTitle  = sizeof( szPictureName );
  328.             ofn.Flags =
  329.                    OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
  330.  
  331.             if( GetOpenFileName( &ofn ))
  332.                {   // Save the current filter index
  333.                 dwFilterIndex = ofn.nFilterIndex;
  334.                 LaunchPictureWnd( szPicturePath, szPictureName );
  335.                }
  336.             else if( dwError = CommDlgExtendedError())
  337.                {  // Tell the user about the error
  338.                 TellUserCommonDlgError( dwError );
  339.                }
  340.  
  341.             return 0L;
  342.  
  343.          case VIEWER_FILE_CLOSE:
  344.             if( ( hwndPicture = (HWND) SendMessage
  345.                              ( g.hwndClient, WM_MDIGETACTIVE, 0, 0L )) &&
  346.                                                    IsWindow( hwndPicture ))
  347.                 SendMessage( hwndPicture, WM_CLOSE, 0, 0L );
  348.  
  349.             return 0L;
  350.  
  351.          case VIEWER_FILE_PRTSETUP:
  352.             memset( &pd, 0, sizeof( PRINTDLG ));
  353.  
  354.             pd.lStructSize = sizeof( PRINTDLG );
  355.             pd.hwndOwner   = hwndFrame;
  356.             pd.Flags       = PD_PRINTSETUP;
  357.  
  358.             if( ( PrintDlg( &pd ) == 0 ) &&
  359.                                      ( dwError = CommDlgExtendedError()))
  360.                {  // Tell the user about the error
  361.                 TellUserCommonDlgError( dwError );
  362.                }
  363.  
  364.             return 0L;
  365.  
  366.          case VIEWER_FILE_PRINT:
  367.                // Customize the common dlg to eliminate some options that are 
  368.                // not useful. This requires a new template and a hook proc
  369.             memset( &pd, 0, sizeof( PRINTDLG ));
  370.  
  371.             pd.lStructSize = sizeof( PRINTDLG );
  372.             pd.hwndOwner   = hwndFrame;
  373.             pd.Flags       = PD_RETURNDC |
  374.                                  PD_ENABLEPRINTHOOK | PD_ENABLEPRINTTEMPLATE;
  375.             pd.hInstance   = ViewerQueryResources();
  376.             pd.lpPrintTemplateName = MAKEINTRESOURCE( CUSTOM_DLG_COMN_PRINT );
  377.             if( !( pd.lpfnPrintHook =  (PRINTDLGHOOKPROC) 
  378.                       MakeProcInstance( (FARPROC) PrintDlgHookProc,
  379.                                                      ViewerQueryInstance())))
  380.                {CommonTellUser( ViewerQueryResources(), 
  381.                                       VIEWER_STRING_NOMEMORY, NULL, MB_OK );
  382.                 return 0L;
  383.                }
  384.  
  385.             if( PrintDlg( &pd ) != 0 )
  386.                {lpPrtCancelProc = (DLGPROC) MakeProcInstance
  387.                     ( (FARPROC) PrintCancelDlgProc, ViewerQueryInstance() );
  388.  
  389.                 lpPrintAbortProc = (ABORTPROC) MakeProcInstance
  390.                        ( (FARPROC) PrintAbortProc, ViewerQueryInstance() );
  391.  
  392.                 if( !lpPrtCancelProc || !lpPrintAbortProc )
  393.                    {CommonTellUser( ViewerQueryResources(), 
  394.                                      VIEWER_STRING_NOMEMORY, NULL, MB_OK );
  395.                     return 0L;
  396.                    }
  397.  
  398.                 g.bUserAbortPrint = FALSE;
  399.                 nError   = 0;
  400.                 wIDError = 0;
  401.  
  402.                 if( !(g.hwndCancelPrt =
  403.                         CreateDialog( ViewerQueryResources(),
  404.                             MAKEINTRESOURCE( VIEWER_DLG_PRINTCANCEL ),
  405.                                              hwndFrame, lpPrtCancelProc )))
  406.                    {wIDError = VIEWER_STRING_CANCELDLG;
  407.                    }
  408.                 else
  409.                    {EnableWindow( hwndFrame, FALSE );   // disable frame window
  410.  
  411.                     if( SetAbortProc( pd.hDC, lpPrintAbortProc ) <= 0 )
  412.                         wIDError = VIEWER_STRING_ABORTPROC;
  413.                     else
  414.                        {if( hwndPicture = (HWND) SendMessage
  415.                                   ( g.hwndClient, WM_MDIGETACTIVE, 0, 0L ))
  416.                             nError = (int) SendMessage( hwndPicture,
  417.                                        WM_VIEWER_PRINTPICTURE, 0,
  418.                                               (LPARAM) (LPPRINTDLG) &pd );
  419.                         if( ( nError < 0 ) &&
  420.                                   ( nError & SP_NOTREPORTED ) &&
  421.                                                    !g.bUserAbortPrint )
  422.                            {switch( nError )
  423.                                {case SP_APPABORT:
  424.                                 case SP_USERABORT:
  425.                                     break;
  426.                                 case SP_OUTOFDISK:
  427.                                     wIDError = VIEWER_STRING_PRT_OUTOFDISK;
  428.                                     break;
  429.                                 case SP_OUTOFMEMORY:
  430.                                     wIDError = VIEWER_STRING_PRT_NOMEMORY;
  431.                                     break;
  432.                                 case SP_ERROR:   // fall through
  433.                                 default:
  434.                                     wIDError = VIEWER_STRING_PRT_GENERROR;
  435.                                     break;
  436.                                }
  437.                            }
  438.                        }
  439.  
  440.                       // reenable frame window
  441.                     EnableWindow( hwndFrame, TRUE ); 
  442.  
  443.                     if( g.hwndCancelPrt )
  444.                         DestroyWindow( g.hwndCancelPrt );
  445.                    }
  446.  
  447.                 if( wIDError )
  448.                     CommonTellUser( ViewerQueryResources(), wIDError,
  449.                                       VIEWER_STRING_PRT_CAPTION, MB_OK );
  450.  
  451.                 FreeProcInstance( (FARPROC) lpPrtCancelProc );
  452.                 FreeProcInstance( (FARPROC) lpPrintAbortProc );
  453.  
  454.                 if( pd.hDC )
  455.                     DeleteDC( pd.hDC );
  456.                 if( pd.hDevMode != NULL )
  457.                     GlobalFree( pd.hDevMode );
  458.                 if( pd.hDevNames != NULL )
  459.                     GlobalFree( pd.hDevNames );
  460.                }
  461.             else if( dwError = CommDlgExtendedError())
  462.                {  // Tell the user about the error
  463.                 TellUserCommonDlgError( dwError );
  464.                }
  465.  
  466.             return 0L;
  467.  
  468.          case VIEWER_FILE_EXIT:
  469.             SendMessage( hwndFrame, WM_CLOSE, 0, 0L );
  470.             return 0L;
  471.         }
  472.  
  473.       return 0L;      // should never get here
  474.  
  475.      }
  476.  
  477.  
  478. // Function: ViewerWindowCommands - Process WM_COMMAND, Window popup messages
  479. // --------------------------------------------------------------------
  480. // Parameters: HWND   hwndFrame;      Frame window
  481. //             WORD   wIDItem;        Menu or control id
  482. //             WORD   wNotifyCode;    notification message
  483. //
  484. // Returns:    LONG   generally 0L
  485. // --------------------------------------------------------------------
  486.    static LONG NEAR ViewerWindowCommands
  487.                        (HWND hwndFrame, WPARAM wIDItem, WORD wNotifyCode )
  488.  
  489.    // This is standard MDI stuff. 
  490.      {
  491.       switch( wIDItem )
  492.         {case VIEWER_WINDOW_TILE:
  493.             SendMessage( g.hwndClient, WM_MDITILE, 0, 0L );
  494.             return 0L;
  495.  
  496.          case VIEWER_WINDOW_CASCADE:
  497.             SendMessage( g.hwndClient, WM_MDICASCADE, 0, 0L );
  498.             return 0L;
  499.  
  500.          case VIEWER_WINDOW_ARRANGE:
  501.             SendMessage( g.hwndClient, WM_MDIICONARRANGE, 0, 0L );
  502.             return 0L;
  503.         }
  504.  
  505.       return 0L;      // should never get here
  506.  
  507.      }
  508.  
  509.  
  510. // Function: ViewerHelpCommands - Process WM_COMMAND, Help popup messages
  511. // --------------------------------------------------------------------
  512. // Parameters: HWND   hwndFrame;      Frame window
  513. //             WORD   wIDItem;        Menu or control id
  514. //             WORD   wNotifyCode;    notification message
  515. //
  516. // Returns:    LONG   generally 0L
  517. // --------------------------------------------------------------------
  518.    static LONG NEAR ViewerHelpCommands
  519.                        (HWND hwndFrame, WPARAM wIDItem, WORD wNotifyCode )
  520.  
  521.      {char       szHelp[MAX_PATH_LEN];    // Help file path
  522.       DLGPROC    lpDlgProc;               // -> dialog proc
  523.  
  524.       switch( wIDItem )
  525.         {case VIEWER_HELP_VIEWERHELP:
  526.             CommonGetLocalizedHelpFile
  527.                       ( VIEWER_ROOT_NAME, szHelp, ViewerQueryInstance() );
  528.  
  529.             if( szHelp[0] )
  530.                 WinHelp( hwndFrame, (LPCSTR) szHelp, HELP_CONTENTS, 0L );
  531.             else
  532.                 CommonTellUser( ViewerQueryResources(),
  533.                                  VIEWER_STRING_NOHELPFILE,
  534.                                         VIEWER_STRING_CAPTION, MB_OK );
  535.  
  536.             return 0L;
  537.  
  538.          case VIEWER_HELP_USINGHELP:
  539.             WinHelp( hwndFrame, (LPCSTR) "WINHELP.HLP", HELP_CONTENTS, 0L );
  540.             return 0L;
  541.  
  542.          case VIEWER_HELP_ABOUTVIEWER:
  543.             if( ( g.hAboutBitmap = LoadBitmap( ViewerQueryResources(),
  544.                            MAKEINTRESOURCE( VIEWER_VIEWER_BITMAP ))) &&
  545.                   ( lpDlgProc = (DLGPROC) MakeProcInstance
  546.                         ( (FARPROC) AboutDlgProc, ViewerQueryInstance())))
  547.                {DialogBox( ViewerQueryResources(),
  548.                           MAKEINTRESOURCE( VIEWER_DLG_ABOUTVIEWER ),
  549.                                                 hwndFrame, lpDlgProc );
  550.                 FreeProcInstance( (FARPROC) lpDlgProc );
  551.                }
  552.             else
  553.                 CommonTellUser( ViewerQueryResources(),
  554.                                  VIEWER_STRING_NOMEMORY,
  555.                                         VIEWER_STRING_CAPTION, MB_OK );
  556.             if( g.hAboutBitmap )
  557.                 DeleteObject( g.hAboutBitmap );
  558.             g.hAboutBitmap = NULL;
  559.  
  560.             return 0L;
  561.         }
  562.  
  563.       return 0L;      // should never get here
  564.  
  565.      }
  566.  
  567.  
  568. // Function: CloseEnumProc - Close all enumerate proc
  569. // --------------------------------------------------------------------
  570. // Parameters: As required by Microsoft Windows
  571. //
  572. // Returns:    Always TRUE to enumerate all windows
  573. // --------------------------------------------------------------------
  574.    BOOL __export CALLBACK CloseEnumProc( HWND hwnd, LPARAM lParam )
  575.  
  576.      {char    szClassName[40];      // Temp buffer for class name
  577.  
  578.    // Check class name since there are several classes of child windows
  579.    // These include scroll bars etc that appear in picture windows
  580.       if( !GetClassName( hwnd, szClassName, sizeof( szClassName )) ||
  581.                            lstrcmpi( szClassName, VIEWER_PICTURE_CLASS ))
  582.           return TRUE;
  583.  
  584.           // If someone doesn't want to quit, stop enumeration
  585.       if( !SendMessage( hwnd, WM_QUERYENDSESSION, 0, 0L ))
  586.           return FALSE;
  587.  
  588.       SendMessage( GetParent( hwnd ), WM_MDIDESTROY, (WPARAM) hwnd, 0L );
  589.  
  590.       return TRUE;
  591.      }
  592.  
  593. // Function: PaletteEnumProc - Tells all child wnds to repaint because
  594. //                             of palette change
  595. // --------------------------------------------------------------------
  596. // Parameters: As required by Microsoft Windows
  597. //
  598. // Returns:    Always TRUE to enumerate all windows
  599. // --------------------------------------------------------------------
  600.    BOOL __export CALLBACK PaletteEnumProc( HWND hwnd, LPARAM lParam )
  601.  
  602.      {char    szClassName[40];      // Temp buffer for class name
  603.  
  604.    // Check class name since there are several classes of child windows
  605.    // These include scroll bars etc that appear in picture windows
  606.       if( !GetClassName( hwnd, szClassName, sizeof( szClassName )) ||
  607.                            lstrcmpi( szClassName, VIEWER_PICTURE_CLASS ))
  608.           return TRUE;
  609.  
  610.       if( hwnd != (HWND) LOWORD( lParam ))
  611.           InvalidateRect( hwnd, NULL, FALSE );
  612.  
  613.       return TRUE;
  614.      }
  615.  
  616.  
  617. // Function: LaunchPictureWnd - tell hwndClient to launch a picture wnd
  618. // --------------------------------------------------------------------
  619. // Parameters: LPSTR    lpPicturePath        Path of picture file
  620. //             LPSTR    lpName               File name of picture
  621. //
  622. // Returns:    LONG     generally 0L
  623. // --------------------------------------------------------------------
  624.    static LONG NEAR LaunchPictureWnd( LPSTR lpPicturePath, LPSTR lpName )
  625.  
  626.      {MDICREATESTRUCT       mdicreate;     // mdi create struct
  627.       HWND                  hwndPicture;   // Temp handle of window
  628.  
  629.       if( !lpPicturePath[0] )
  630.           return -1L;
  631.  
  632.       if( lpName == NULL )
  633.           {lpName = lpPicturePath + lstrlen( lpPicturePath );
  634.            lpName = AnsiPrev( lpPicturePath, lpName );
  635.            while( *lpName && (*lpName != '\\') && (lpName != lpPicturePath))
  636.               lpName = AnsiPrev( lpPicturePath, lpName );
  637.            if( *lpName == '\\' )
  638.               lpName = AnsiNext( lpName );
  639.           }
  640.  
  641.       mdicreate.szClass = VIEWER_PICTURE_CLASS;
  642.       mdicreate.szTitle = lpName;
  643.       mdicreate.hOwner  = ViewerQueryInstance();
  644.       mdicreate.x       = CW_USEDEFAULT;
  645.       mdicreate.y       = CW_USEDEFAULT;
  646.       mdicreate.cx      = CW_USEDEFAULT;
  647.       mdicreate.cy      = CW_USEDEFAULT;
  648.       mdicreate.style   = MDIS_ALLCHILDSTYLES | WS_CLIPCHILDREN;
  649.       mdicreate.lParam  = (LPARAM) lpPicturePath;
  650.  
  651.       if( !( hwndPicture = (HWND) SendMessage
  652.                   ( g.hwndClient, WM_MDICREATE, 0,
  653.                               (LPARAM) (LPMDICREATESTRUCT) &mdicreate )))
  654.          {return -1L;
  655.          }
  656.       else
  657.          {if(++g.wNumPictures == 1 )
  658.              ViewerEnableMenus( ViewerQueryFrameWindow(), TRUE );
  659.  
  660.           return 0L;
  661.          }
  662.      }
  663.  
  664.  
  665. // Function: ProcessDroppedFiles - Process the WM_DROPFILES message
  666. // --------------------------------------------------------------------
  667. // Parameters: HWND     hwndFrame         Frame window handle
  668. //             WPARAM   wParam            Message wParam
  669. //
  670. // Returns:    LONG     Always 0L;
  671. // --------------------------------------------------------------------
  672.    static LONG NEAR ProcessDroppedFiles( HWND hwndFrame, WPARAM wParam )
  673.  
  674.      {int           i;                  // Temp counter
  675.       int           nNumFiles;          // Temp number of dropped files
  676.       UINT          uBytes;             // Temp len of drop file path
  677.       char          szDropFile[MAX_PATH_LEN];  // Temp drop file path
  678.       
  679.       if( nNumFiles = DragQueryFile( (HDROP) wParam, 0xffff,
  680.                                                       (LPSTR) NULL, 0 ))
  681.          {  // Create processing requires that frame window has
  682.             // nonzero dimensions so first restore iconic window
  683.           if( IsIconic( hwndFrame ))
  684.               ShowWindow( hwndFrame, SW_SHOWNORMAL );
  685.  
  686.           for( i=0; i < nNumFiles; i++ )
  687.              {uBytes = DragQueryFile( (HDROP) wParam, i,
  688.                               (LPSTR) szDropFile, sizeof( szDropFile ));
  689.               if( uBytes > 0 )
  690.                   LaunchPictureWnd( szDropFile, NULL );
  691.              }
  692.          }
  693.  
  694.       DragFinish( (HDROP) wParam );
  695.  
  696.       return 0L;
  697.      }
  698.  
  699. // Function: DestroyHelpInstance - Tell windows that instance is done with
  700. //                                 help. This is called as a function so that
  701. //                                 szHelp[] is not an automatic var. in the
  702. //                                 winproc
  703. // --------------------------------------------------------------------
  704. // Parameters: HWND     hwndFrame         Frame window handle
  705. //
  706. // Returns:    VOID
  707. // --------------------------------------------------------------------
  708.    static VOID NEAR DestroyHelpInstance( HWND hwndFrame )
  709.  
  710.      {char          szHelp[MAX_PATH_LEN];  // Help file name
  711.  
  712.       WinHelp( hwndFrame, CommonGetLocalizedHelpFile
  713.                     ( VIEWER_ROOT_NAME, szHelp, ViewerQueryResources() ),
  714.                                                      HELP_QUIT, NULL );
  715.       return;
  716.      }
  717.  
  718. // Function: AboutDlgProc - About dialog proc
  719. // --------------------------------------------------------------------
  720. // Parameters: As required by Microsoft Windows
  721. //
  722. // Returns:    As required by Microsoft Windows
  723. // --------------------------------------------------------------------
  724.    BOOL __export CALLBACK AboutDlgProc
  725.                      ( HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam )
  726.  
  727.      {BITMAP       bm;                 // Temp bitmap struct
  728.       HWND         hwndCntrl;          // Handle of rect control that is painted
  729.                                        // over with bitmap
  730.       HDC          hdestDC;            // hdc of control rect
  731.       HDC          hmemDC;             // Memory dc
  732.       RECT         rcdestRect;         // Rect of control
  733.       HBITMAP      hbitmapSave;        // return from select object
  734.       PAINTSTRUCT  ps;                 // Paint struct
  735.  
  736.  
  737.       switch( msg )
  738.         {case WM_COMMAND:
  739.             EndDialog( hdlg, 0 );
  740.             return TRUE;
  741.  
  742.          case WM_PAINT:
  743.    // Don't bother with error messages since only effect is that
  744.    // bitmap will not appear in dialog
  745.             if( !BeginPaint( hdlg, &ps ))
  746.                 return FALSE;
  747.             EndPaint( hdlg, &ps );
  748.  
  749.             if( !g.hAboutBitmap || 
  750.                   !( hwndCntrl = GetDlgItem( hdlg, VIEWER_ABOUT_BMPFRAME )))
  751.                 return FALSE;
  752.  
  753.             InvalidateRect( hwndCntrl, NULL, TRUE );
  754.             UpdateWindow( hwndCntrl );
  755.  
  756.             if( !(hdestDC = GetDC( hwndCntrl )))
  757.                 return FALSE;
  758.  
  759.             if( hmemDC = CreateCompatibleDC( hdestDC ))
  760.                {if( hbitmapSave = SelectObject( hmemDC, g.hAboutBitmap ))
  761.                    {GetObject( g.hAboutBitmap, sizeof( BITMAP ), &bm );
  762.                     GetClientRect( hwndCntrl, &rcdestRect );
  763.  
  764.                     BitBlt( hdestDC, 
  765.                             ( rcdestRect.right - bm.bmWidth ) / 2,
  766.                             ( rcdestRect.bottom - bm.bmHeight ) / 2, 
  767.                             bm.bmWidth, bm.bmHeight, hmemDC, 0, 0, SRCCOPY );
  768.  
  769.                     SelectObject( hmemDC, hbitmapSave );
  770.                    }
  771.  
  772.                 DeleteDC( hmemDC );
  773.                }
  774.  
  775.             ReleaseDC( hwndCntrl, hdestDC );
  776.  
  777.             return FALSE;
  778.  
  779.          default:
  780.             return FALSE;
  781.         }
  782.  
  783.       return FALSE;
  784.      }
  785.  
  786.  
  787. // Function: PrintAbortProc - Print abort proc
  788. // --------------------------------------------------------------------
  789. // Parameters: As required by Microsoft Windows
  790. //
  791. // Returns:    As required by Microsoft Windows
  792. // --------------------------------------------------------------------
  793.    int __export CALLBACK PrintAbortProc( HDC hdc, int nCode )
  794.  
  795.      {MSG     msg;          // Message struct
  796.  
  797.       while( !g.bUserAbortPrint &&
  798.                       PeekMessage( &msg, NULL, NULL, NULL, PM_REMOVE ))
  799.          {if( !g.hwndCancelPrt || !IsDialogMessage( g.hwndCancelPrt, &msg ))
  800.              {TranslateMessage( &msg );
  801.               DispatchMessage( &msg );
  802.              }
  803.          }
  804.  
  805.       return !g.bUserAbortPrint;
  806.      }
  807.  
  808. // Function: PrintCancelDlgProc - User cancel printing dlg proc
  809. // --------------------------------------------------------------------
  810. // Parameters: As required by Microsoft Windows
  811. //
  812. // Returns:    As required by Microsoft Windows
  813. // --------------------------------------------------------------------
  814.    BOOL __export CALLBACK PrintCancelDlgProc
  815.                      ( HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam )
  816.  
  817.      {char    szName[50];        // Buffer for picture name
  818.  
  819.       switch( msg )
  820.          {case WM_INITDIALOG:
  821.              SetFocus( GetDlgItem( hdlg, IDCANCEL ));
  822.              SetDlgItemText( hdlg, PRINT_CANCEL_PICTURENAME,
  823.                                 ViewerQueryActivePictureName( szName ));
  824.              return TRUE;
  825.  
  826.           case WM_COMMAND:
  827.              return ( g.bUserAbortPrint = TRUE );
  828.  
  829.           case WM_DESTROY:
  830.              g.hwndCancelPrt = NULL;
  831.              break;
  832.          }
  833.  
  834.       return FALSE;
  835.      }
  836.  
  837.  
  838. // Function: PrintDlgHookProc - Custom print common dlg hook function
  839. // --------------------------------------------------------------------
  840. // Parameters: As required by Microsoft Windows
  841. //
  842. // Returns:    As required by Microsoft Windows
  843. // --------------------------------------------------------------------
  844.    UINT __export CALLBACK PrintDlgHookProc
  845.                    (HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam )
  846.  
  847.      {    // The dialog ids are defined in dlgs.h
  848.           // Array of ids of controls to be hidden
  849.       static int nIDs[] = {grp1, rad1, rad2, rad3, stc2, edt1, 
  850.                            stc3, edt2, chx1, chx2, pshHelp };
  851.       UINT   i;            // Temp counter
  852.      
  853.       if( message == WM_INITDIALOG )
  854.          {for( i=0; i < ( sizeof( nIDs ) / sizeof( nIDs[0] )); i++ )
  855.               ShowWindow( GetDlgItem( hdlg, nIDs[i] ), SW_HIDE );
  856.  
  857.           return TRUE;
  858.          }
  859.       else
  860.           return FALSE;
  861.      }
  862.  
  863.  
  864. // Function: ViewerEnableMenus - Disables menu items when there
  865. //                               are no pictures
  866. // --------------------------------------------------------------------
  867. // Parameters: HWND       hwndFrame      Handle of frame window
  868. //             BOOL       bEnable        Enabling flag
  869. //
  870. // Returns:    VOID
  871. // --------------------------------------------------------------------
  872.    static VOID NEAR ViewerEnableMenus( HWND hwndFrame, BOOL bEnable )
  873.  
  874.      {UINT    fFlag;            // Temp enabling flag
  875.       HMENU   hmenuFrame;       // Handle to main menu of frame window
  876.       UINT    i;                // Index
  877.  
  878.       static UINT uMenuIDs[] = {VIEWER_FILE_CLOSE,
  879.                                 VIEWER_FILE_PRINT,
  880.  
  881.                                 VIEWER_EDIT_COPYPICTURE,
  882.                                 VIEWER_EDIT_OPTIONS,
  883.                                 VIEWER_EDIT_CANCELSEL,
  884.  
  885.                                 VIEWER_IMAGE_GETINFO,
  886.                                 VIEWER_IMAGE_HALFSIZE,
  887.                                 VIEWER_IMAGE_NORMALSIZE,
  888.                                 VIEWER_IMAGE_DOUBLESIZE,
  889.  
  890.                                 VIEWER_WINDOW_TILE,
  891.                                 VIEWER_WINDOW_CASCADE,
  892.                                 VIEWER_WINDOW_ARRANGE
  893.                                };
  894.  
  895.       if( !( hmenuFrame = GetMenu( hwndFrame )))
  896.           return;
  897.  
  898.       fFlag = (bEnable ? MF_ENABLED : MF_GRAYED ) | MF_BYCOMMAND;
  899.       for( i=0; i < sizeof( uMenuIDs ) / sizeof( uMenuIDs[0] ); i++ )
  900.           EnableMenuItem( hmenuFrame, uMenuIDs[i], fFlag );
  901.           
  902.       DrawMenuBar( hwndFrame );
  903.  
  904.       return;
  905.      }
  906.  
  907.  
  908. // Function: TellUserCommonDlgError - Tell the user about the common dlg
  909. //                                    error
  910. // --------------------------------------------------------------------
  911. // Parameters: DWORD       dwError      error code returned by common dlg
  912. //
  913. // Returns:    VOID
  914. // --------------------------------------------------------------------
  915.    static VOID NEAR TellUserCommonDlgError( DWORD dwError )
  916.  
  917.      {WORD          wIDErrorString;   // String id
  918.  
  919.    // Not much here now, can make this as explicit as desired
  920.    // Now returns text of error id, i.e. "CDERR_INITIALIZATION"
  921.    // Not all messages are explicitly included
  922.  
  923.       switch( dwError )
  924.          {case CDERR_FINDRESFAILURE: 
  925.               wIDErrorString = VIEWER_STRING_CDLG_FINDRESFAIL;
  926.               break;
  927.           case CDERR_INITIALIZATION:
  928.               wIDErrorString = VIEWER_STRING_CDLG_INITFAIL;
  929.               break;
  930.           case CDERR_LOADRESFAILURE:
  931.               wIDErrorString = VIEWER_STRING_CDLG_LOADRESFAIL;
  932.               break;
  933.           case CDERR_LOCKRESFAILURE:
  934.               wIDErrorString = VIEWER_STRING_CDLG_LOCKRESFAIL;
  935.               break;
  936.           case CDERR_MEMALLOCFAILURE:
  937.               wIDErrorString = VIEWER_STRING_CDLG_MEMALLOCFAIL;
  938.               break;
  939.           case CDERR_MEMLOCKFAILURE:
  940.               wIDErrorString = VIEWER_STRING_CDLG_MEMLOCKFAIL;
  941.               break;
  942.           case CDERR_STRUCTSIZE:
  943.               wIDErrorString = VIEWER_STRING_CDLG_STRUCTSIZE;
  944.               break;
  945.           case FNERR_INVALIDFILENAME:
  946.               wIDErrorString = VIEWER_STRING_CDLG_BADFILENAME;
  947.               break;
  948.           case PDERR_INITFAILURE:
  949.               wIDErrorString = VIEWER_STRING_CDLG_PRTINITFAIL;
  950.               break;
  951.           case PDERR_LOADDRVFAILURE:
  952.               wIDErrorString = VIEWER_STRING_CDLG_LOADDRVFAIL;
  953.               break;
  954.           case PDERR_NODEFAULTPRN:
  955.               wIDErrorString = VIEWER_STRING_CDLG_NODEFPRINTER;
  956.               break;
  957.           case PDERR_NODEVICES:
  958.               wIDErrorString = VIEWER_STRING_CDLG_NODEVICES;
  959.               break;
  960.           case PDERR_PRINTERNOTFOUND:
  961.               wIDErrorString = VIEWER_STRING_CDLG_NOFINDPNTR;
  962.               break;
  963.           case PDERR_SETUPFAILURE:
  964.               wIDErrorString = VIEWER_STRING_CDLG_SETUPFAIL;
  965.               break;
  966.           default:
  967.               wIDErrorString = VIEWER_STRING_CDLG_GENFAILURE;
  968.               break;
  969.          }
  970.  
  971.       if( wIDErrorString == VIEWER_STRING_CDLG_GENFAILURE )
  972.           CommonTellUser( ViewerQueryResources(),
  973.                          VIEWER_STRING_CDLG_GENFAILURE,
  974.                                VIEWER_STRING_CDLG_CAP, MB_OK, dwError );
  975.       else
  976.           CommonTellUser( ViewerQueryResources(),
  977.                      VIEWER_STRING_CDLG_FORMAT, VIEWER_STRING_CDLG_CAP,
  978.                                                   MB_OK, wIDErrorString );
  979.       return;
  980.  
  981.      }
  982.  
  983.  
  984. //  The remaining functions are the query functions called by other modules
  985.  
  986. // Function: ViewerQueryClientWindow - Query Client Window Handle
  987. // --------------------------------------------------------------------
  988. // Parameters: None.
  989. //
  990. // Returns:    HWND g.hwndClient;        MDI client window handle
  991. // --------------------------------------------------------------------
  992.    HWND FAR ViewerQueryClientWindow( VOID )
  993.  
  994.      {return g.hwndClient;
  995.      }
  996.  
  997. // Function: ViewerQueryNumPictures - Query number of pictures
  998. // --------------------------------------------------------------------
  999. // Parameters: None.
  1000. //
  1001. // Returns:    HWND g.wNumPictures;    Number of pictures
  1002. // --------------------------------------------------------------------
  1003.    WORD FAR ViewerQueryNumPictures( VOID )
  1004.  
  1005.      {return g.wNumPictures;
  1006.      }
  1007.